﻿using System;

namespace jsonar
{
	internal sealed class String : Json
	{
		public readonly static String EMPTY = new String("");
		private static string ConvString2Json(string str)
		{
			if (str == null || str.Length < 1) return str;
			System.Text.StringBuilder sb = new System.Text.StringBuilder(str.Length + 50);
			foreach (char c in str)
			{
				if (c == '"') sb.Append("\\\"");
				else if (c == '\\') sb.Append("\\\\");
				else if (c == '\r') sb.Append("\\r");
				else if (c == '\n') sb.Append("\\n");
				else if (c == '\t') sb.Append("\\t");
				else if (c == '\b') sb.Append("\\b");
				else if (c == '\f') sb.Append("\\f");
				else if (c == '/') sb.Append("\\/");
				//else if (c < 33 || c > 126) { sb.Append("\\u"); sb.Append(((int)c).ToString("X4")); }
				else if (c < 33 || (c > 126 && c < 0x4e00) || c > 0x9fa5) { sb.Append("\\u"); sb.Append(((int)c).ToString("X4")); }
				else sb.Append(c);
			}
			return sb.ToString();
		}
		public static string ConvJson2String(string jstr)
		{
			if (jstr == null || jstr.Length < 1) return jstr;
			System.Text.StringBuilder sb = new System.Text.StringBuilder(jstr.Length);
			int idx = -1;int len = jstr.Length ; char c;
			while (++idx < len)
			{
				c = jstr[idx];
				if (c != '\\' || idx + 1 >= len) { sb.Append(c); continue; }
				c = jstr[++idx];
				if (c == '\\') sb.Append("\\");
				else if (c == 'r') sb.Append("\r");
				else if (c == '"') sb.Append("\"");
				else if (c == 'n') sb.Append("\n");
				else if (c == 't') sb.Append("\t");
				else if (c == 'b') sb.Append("\b");
				else if (c == 'f') sb.Append("\f");
				else if (c == '/') sb.Append("/");
				else if (c == 'u')
				{
					idx += 4;
					if (idx < jstr.Length)
					{
						try { sb.Append((char)int.Parse(jstr.Substring(idx - 3, 4), System.Globalization.NumberStyles.HexNumber)); }
						catch { }
					}
				}
				else sb.Append(c);
			}
			return sb.ToString();
		}


		public string Val() { return this.val; }
		private string val = null;
		private string _val = null;

		public String(string str) {
			if (str == null) return;
			this.val = str;
			this._val = ConvString2Json(str);
		}

		public override int getValue(int dft) { if (this.val == null || this.val.Length < 1) return dft; try { return System.Convert.ToInt32(this.val); } catch { return dft; } }
		public override uint getValue(uint dft) { if (this.val == null || this.val.Length < 1) return dft; try { return System.Convert.ToUInt32(this.val); } catch { return dft; } }
		public override long getValue(long dft) { if (this.val == null || this.val.Length < 1) return dft; try { return System.Convert.ToInt64(this.val); } catch { return dft; } }
		public override float getValue(float dft) { if (this.val == null || this.val.Length < 1) return dft; try { return System.Convert.ToSingle(this.val); } catch { return dft; } }
		public override double getValue(double dft) { if (this.val == null || this.val.Length < 1) return dft; try { return System.Convert.ToDouble(this.val); } catch { return dft; } }
		public override decimal getValue(decimal dft) { if (this.val == null || this.val.Length < 1) return dft; try { return System.Convert.ToDecimal(this.val); } catch { return dft; } }
		public override bool getValue(bool dft) { if (this.val == "1" || this.val == "true") return true; if (this.val == "0" || this.val == "false") return false; return dft; }
		public override string getValue(string val) { return this.val; }

		public override string ToString() { return "\"" + this._val + "\""; }
		public override string toHtml()
		{
			if (val == null) return null; return "\"" + this.val.Replace("<", "&lt;").Replace(">", "&gt;") + "\"";
		}
	}
}
